#include <cstdint>
#include <cstring>
#include <cstdio>
#include "BtMsghandler.h"
#include "hzkHandler.h"

#ifdef MINI_GLOG
#include "miniglog/logging.h"
#endif

#include <chrono>
#ifndef LT_BLE_ANDROID
#import <NotificationCenter/NotificationCenter.h>
#import "SDKHeader.h"
#endif

//先高位，再低位
unsigned short ltParseUShort(unsigned char stream0, unsigned char stream1){
    unsigned short rtn=stream1;
    rtn += (stream0 << 8);
    return rtn;
}
unsigned short ltParseUShort(const unsigned char* pStream){
    unsigned short rtn=pStream[1];
    rtn += (pStream[0] << 8);
    return rtn;
}
bool CLtPkgHeader::init(const unsigned char* pData, int dataLen)
{
    if(!isHeadReceived(dataLen)){
        return false;
    }
    if(!isAckPkg(*pData) && !isRcvPkg(*pData)){
        return false;
    }
    headByte=*pData;
    pkgLen=ltParseUShort(pData+1);
    if(pkgLen<LT_MIN_PKG_LEN || pkgLen>LT_PKG_LEN){
        return false;
    }
    taskId=pData[3];
    if(!isValidTaskId(taskId)){
        return false;
    }
    storeId=pData[4];
    pkgSum=ltParseUShort(pData+5);
    pkgSeq=ltParseUShort(pData+7);
    if(pkgSeq>=pkgSum){
        return false;
    }
    return true;
}
bool CLtPkgHeader::isValidHead(const unsigned char* pData, int dataLen)//只检查前9个字节（包头）
{
    if(!isHeadReceived(dataLen)){
        return false;
    }
    if(!isAckPkg(*pData) && !isRcvPkg(*pData)){
        return false;
    }
    unsigned short pkgLen=ltParseUShort(pData+1);
    if(pkgLen<LT_MIN_PKG_LEN || pkgLen>LT_PKG_LEN){
        return false;
    }
    unsigned char taskId=pData[3];
    if(!isValidTaskId(taskId)){
        return false;
    }
    unsigned short pkgSum=ltParseUShort(pData+5);
    unsigned short pkgSeq=ltParseUShort(pData+7);
    if(pkgSeq>=pkgSum){
        return false;
    }
    return true;
}
bool CLtPkgHeader::isValidPkgSt(const unsigned char* pData, int dataLen)
{
    CLtPkgHeader header;
    if(!header.init(pData, dataLen)){
        return false;
    }
    if(dataLen<header.pkgLen){
        return false;//len fail
    }
    unsigned char checkTmp=0;
    for(int i=0;i<header.pkgLen-2;++i){
        checkTmp+=pData[i];
    }
    if(checkTmp!=pData[header.pkgLen-2]){
        return false;//check fail
    }
    if(pData[header.pkgLen-1]!=LT_ENDBYTE && pData[header.pkgLen-1]!=LT_ENDBYTE_LAST){
        return false;
    }
    return true;
}
bool CLtPkgHeader::isValidPkg(const unsigned char* pData, int dataLen)
{
    if(!isValidHead(pData, dataLen)){
        return false;//head fail
    }
    if(dataLen<pkgLen){
        return false;//len fail
    }
    unsigned char checkTmp=0;
    for(int i=0;i<pkgLen-2;++i){
        checkTmp+=pData[i];
    }
    if(checkTmp!=pData[pkgLen-2]){
        return false;//check fail
    }
    if(pData[pkgLen-1]!=LT_ENDBYTE && pData[pkgLen-1]!=LT_ENDBYTE_LAST){
        return false;
    }
    return true;
}
bool CLtPkgHeader::isValidAckPkg(const unsigned char* pData, int dataLen)
{
    CLtPkgHeader header;
    if(!header.init(pData, dataLen)){
        return false;
    }
    bool isOk=header.isValidPkg(pData, dataLen);
    if(!isOk){
        return false;
    }
    if(header.pkgLen!=LT_ACK_PKG_LEN){
        return false;
    }
    if(pData[header.pkgLen-1]!=LT_ENDBYTE_LAST){
        return false;
    }
    if(pData[header.pkgLen-3]!=0 && pData[header.pkgLen-3]!=1){
        return false;
    }
    return true;
}
bool CLtPkgHeader::isPkgReceived(const unsigned char* pData, int dataLen)
{
    unsigned short pkgLen0=ltParseUShort(pData+1);
    return pkgLen0<=dataLen;
}
//return 0正常跳过干扰字节， 1 3发现AA特征字节（包未全，暂时校验无错误）， 2发现ack合法整包 BB， 4发现rcv合法整包
// pData中内容会发生移位，dataLen变成移位后的长度（变小）
int CLtPkgHeader::skip(unsigned char* pData, int &dataLen)
{
    int flag=0;
    if(dataLen<=0){
        return 0;
    }
    int i;
    for( i=1;i<dataLen;++i){
        if(LT_BGBYTE_ACK==pData[i]
          && (!CLtPkgHeader::isAckPkgReceived(dataLen-i) || CLtPkgHeader::isValidAckPkg(pData+i, dataLen-i))) {
            //BB开始，并且（ack数据未接收完毕 或 接收完毕并合法），才进行ack包处理
            LOG(INFO)<<"CLtPkgHeader::skip, get ackpkg(BB), i="<<i<<",len="<<(dataLen-i);
            flag=2;
            break;
        }
        if(LT_BGBYTE==pData[i]){
           if(!CLtPkgHeader::isHeadReceived(dataLen-i)){
               flag=1;//head未收全
               break;
           }
            if(CLtPkgHeader::isValidHead(pData+i, dataLen-i)
              && !CLtPkgHeader::isPkgReceived(pData+i, dataLen-i)){
                flag=3;//head收全且合法 and 整包未收全
                break;
            }
            if(CLtPkgHeader::isValidPkgSt(pData+i, dataLen-i)) {
                flag = 4;//整包合法（需要立刻处理）
                LOG(INFO)<<"CLtPkgHeader::skip, get rcvpkg(AA), i="<<i<<",len="<<(dataLen-i);
                break;
            }
        }
    }
    int k;
    if(i==dataLen){
        //全部跳过
        k=0;
    }else {
        for (k = 0; k < dataLen - 1 && i < dataLen; ++k, ++i) {
            pData[k] = pData[i];
        }
    }
    dataLen=k;
    return flag;
}
int CLtRecvPackage::addData(const unsigned char* pData, int dataLen)
{
    if(dataLen<=0 || NULL==pData){
        LOG(ERROR)<<"CLtRecvPackage::addData failed, dataLen<=0 || NULL==pData";
        return 0;
    }
    //计算要拷贝过来的长度，后面可能有其他包内容
    int addLen=dataLen;
    int pkgLen=0;
    if(!isHeadReceived() && CLtPkgHeader::isHeadReceived(m_dataLen+dataLen)){
        pkgLen=calcPkgLength(pData, dataLen);
    }else if(isHeadReceived()){
        pkgLen=m_header.pkgLen;
    }
    if(pkgLen>LT_PKG_LEN){
        //pkgLen=LT_PKG_LEN;
        //invalid pkg, skip to next 开始字节，如果没有清空当前缓存m_pData
        if(m_dataLen>0){
            skip();
            return 0;
        }else{
            return 1;//跳过一个字节，待下次循环再处理
        }
    }
    if(pkgLen>0) {
        addLen = dataLen + m_dataLen > pkgLen ? pkgLen-m_dataLen : dataLen;
    }

    if(NULL==m_pData && 0==m_dataSize && 0==m_dataLen) {
        //初始化申请内存，按500申请，不足可扩展
        m_dataSize = addLen>LT_PKG_LEN?addLen:LT_PKG_LEN;
        m_pData = new unsigned char[m_dataSize];
    }
    if(addLen>m_dataSize-m_dataLen){
        //扩大缓存
        m_dataSize+=(addLen-(m_dataSize-m_dataLen));
        unsigned char * tmp = new unsigned char[m_dataSize];
        memcpy(tmp, m_pData, m_dataLen);
        delete[] m_pData;
        m_pData=tmp;
    }
    //追加拷贝数据
    memcpy(m_pData+m_dataLen, pData, addLen);
    m_dataLen+=addLen;

    if(isHeadReceived() && !m_isHeadOk){//提取header
        if(isValidHead()){
            m_header.init(m_pData, m_dataLen);
            m_isHeadOk=true;
        }else{
            LOG(INFO)<<"CLtRecvPackage::addData() header get failed, skip";
            skip();
        }
    }
    LOG(INFO)<<"CLtRecvPackage::addData() addLen="<<addLen<<", m_dataLen="<<m_dataLen<<", m_isHeadOk="<<m_isHeadOk<<", pkgLen="<<pkgLen;
    if(m_isHeadOk && m_dataLen==pkgLen){
        //检查是否接收完毕数据
        if(isValidRcvPkg()) {
            m_isPkgOk = true;
            LOG(INFO) << "CLtRecvPackage::addData() pkgOk ****** seq=" << m_header.pkgSeq << ",sum="
                      << m_header.pkgSum;
        }else{
            skip();
        }
    }

    return addLen;
}
bool CLtRecvPackage::isValidRcvPkg()
{
    if(!m_header.isValidPkg(m_pData, m_dataLen)){
        return false;
    }
    return true;
}
//跳到下一个起始字节AA或BB，如果没有清空整个缓冲区，如果是BB，切换到ack接收状态
void CLtRecvPackage::skip()
{
    m_isHeadOk=false;
    int flag = CLtPkgHeader::skip(m_pData, m_dataLen);
    if (flag == 2) {
        m_bSkipToAck = true;//包含有合法的ack包，或者不足一个长度的ack包，需要切换到ack处理模式
    }else if(flag==4){
        if(m_header.init(m_pData, m_dataLen) && isValidRcvPkg()){
            LOG(INFO)<<"CLtRecvPackage::skip, init pkg ok";
            m_isHeadOk=true;
            m_isPkgOk=true;
            m_dataLen=m_header.pkgLen;//确保完整长度，忽略掉后面字节
            m_bSkipToGoodRcv=true;
        }else{
            LOG(INFO)<<"CLtRecvPackage::skip, init pkg failed, give up data!";
            m_dataLen=0;//应该不会执行到，完整包init失败
        }
    }
}
//根据已有数据+pData，计算包长
unsigned short CLtRecvPackage::calcPkgLength(const unsigned char* pData, int dataLen)
{
    if(m_dataLen>=3){
        return ltParseUShort(m_pData+1);
    }else if(m_dataLen<=0 && dataLen>=3){
        return ltParseUShort(pData+1);
    }else if(m_dataLen==1 && dataLen>=2){
        return ltParseUShort(pData);
    }else if(m_dataLen==2 && dataLen>=1){
        return ltParseUShort(m_pData[1], pData[0]);
    }
    return 0;
}
int CLtAckPackage::init(const unsigned char* pData, int dataLen)
{
    if(!m_header.init(pData, dataLen)){
        return 0;
    }
    m_data=pData[m_header.pkgLen-3];
    return m_header.pkgLen;
}
BtMsghandler::BtMsghandler()
{
    m_pSendData = NULL;
    recv_sta = S0_Recv;
    m_sendList.clear();
    m_exitSendThread = false;
    m_sumRecvPacket=0;
    setSending(false);
    setRecvState(LT_RECV_ST_NONE);
    m_pRecvPkg=NULL;
    m_recvPkgListCount=0;

    m_lck = new  std::unique_lock<std::mutex>(m_mutex);
    if(!m_lck){
        LOG(INFO) << "mutexlock creating for sending data to ble is error";
    }
    m_lckSndBleRlt = new  std::unique_lock<std::mutex>(m_mutexSndBleRlt);
    if(!m_lckSndBleRlt){
        LOG(INFO) << "m_lckSndBleRlt creating for sending data to ble is error";
    }
    m_lckRecvList = new  std::unique_lock<std::mutex>(m_mutexRecvListNotify);
    if(!m_lckRecvList){
        LOG(INFO) << "m_lckRecvList creating  is error";
    }
    m_bRespondPacket = true;
    m_DataLastPos = 0;
    m_mtu=LT_BLE_SIZE_DEF;
    m_pkgDelayMs=PACKAGE_SEND_DELAY;
    setBleDevAckGot(false);
    setSndBleRltGot(false);

    //start thread
    m_thread = new std::thread(&BtMsghandler::makesubPacketandSendTask, this);
    if(!m_thread){
        LOG(INFO) << "thread creating for sending data to ble is error";
    }
    m_thread->joinable();
    m_threadRecv = new std::thread(&BtMsghandler::threadRecvBle, this);
    if(!m_threadRecv){
        LOG(INFO) << "thread creating for sending data to ble is error";
    }
    m_threadRecv->joinable();
}

void BtMsghandler::clrSendList() {
    LOG(INFO) << "clrSendList";
    for (std::list<unsigned char *>::iterator it = m_sendList.begin(); it != m_sendList.end(); it++) {
        unsigned char *p = *it;
        delete[] p;
    }
    m_sendList.clear();
    if (m_pSendData) {
        delete[] m_pSendData;
        m_pSendData = NULL;
    }
}
BtMsghandler::~BtMsghandler()
{
    LOG(INFO) << "un creating BtMsghandler";
    m_exitSendThread = true;
    if(m_pRecvData)
    {
        delete m_pRecvData;
    }
    clrSendList();
    m_cv.notify_one();
    m_cvSndBleRlt.notify_one();
    m_thread->join();
    delete m_thread;
    m_threadRecv->join();
    delete m_threadRecv;
    delete m_lck;
    delete m_lckSndBleRlt;
    delete m_lckRecvList;
    //todo 释放m_recvPkgList m_pRecvPkg

}

// 接收APP层来的数据，每包数据最大20字节
void BtMsghandler::handleBaseBlePackage(const unsigned char* data, const int dataLen) {
    // 是不是一级包中的最后一个二级包来判断是不是药盒回应APP的回应包
    if(NULL == data) {
        LOG(INFO) << "handleBaseBlePackage data == NULL";
        return;
    }
    if(0 >= dataLen) {
        LOG(INFO) << "handleBaseBlePackage 0 >= dataLen";
        return;
    }

    LOG(INFO) << "handleBaseBlePackage, dataLen="<<dataLen;

    std::string strLog;
    char strtmp[5];
    for(int i = 0; i < dataLen; ++i) {
        sprintf(strtmp, "%02x", data[i] & 0x0ff);
        strLog+=strtmp;
    }
    LOG(INFO)<<strLog;

#ifndef LT_BLE_ANDROID
    if(0 == strcmp((char*)data, "\xff")) {
		LOG(INFO) << "handleBaseBlePackage strcmp (data, \xff) == NULL";
        return;
    }
#endif
    int len = dataLen;
//    const unsigned char* data_ = data;
//    do
//    {
//        handleSubPackage(&data_, &len);
//    }while (len);

    /////// hanfei add
    while(len>0) {
        int dealLen = handleRecvBleData(data, len);
        LOG(INFO) << "after handleRecvBleData, rtn dealLen=" << dealLen;
        len -= dealLen;
    }
    LOG(INFO) << "handleBaseBlePackage, end";
}
//返回已处理长度
int BtMsghandler::handleRecvBleData(const unsigned char* data, int dataLen)
{
    LOG(INFO) << "handleRecvBleData m_recvState="<<m_recvState;
    if(isRecvStateNone()){
        if(CLtPkgHeader::isAckPkg(*data)){
            return readAckPkg(data, dataLen);
        }else if(CLtPkgHeader::isRcvPkg(*data)){
            return readRcvPkg(data, dataLen);
        }else{
            return 1;//skip 1 byte(not header byte)
        }
    }else if(isRecvStateAck()){
        return readAckPkg(data, dataLen);
    }else{
        return readRcvPkg(data, dataLen);
    }

}
//返回已处理长度
int BtMsghandler::readAckPkg(const unsigned char *data, int dataLen)
{
    LOG(INFO) << "readAckPkg dataLen="<<dataLen;
    int readLen=m_ackPkg.appendToBuf(data, dataLen);
    if(CLtPkgHeader::isAckPkgReceived(m_ackPkg.m_bufLen)){
        if(CLtPkgHeader::isValidAckPkg(m_ackPkg.m_buf, m_ackPkg.m_bufLen))
        {
            m_ackPkg.init();
            Respond_handle(m_ackPkg.isAckSuccess());
            m_ackPkg.clear();
            setRecvState(LT_RECV_ST_NONE);//处理完ack包，清空状态
            return readLen;
        }else{
            //跳过n字节，直到ack起始字节，或清空buf，重新进行追加并处理
            bool isRcvPkg=false;
            m_ackPkg.skip(isRcvPkg);
            if(m_ackPkg.m_bufLen==0){
                setRecvState(LT_RECV_ST_NONE);//skip全部缓存字节，清除状态
            }else if(isRcvPkg){
                createNewRcvPkg(m_ackPkg.m_buf, m_ackPkg.m_bufLen);
                m_ackPkg.clear();
                setRecvState(LT_RECV_ST_RCV);//因为skip过程中发现AA特征字节，所以切换到rcv状态
            }
            return readLen;//skip n byte(invalid ack)
        }
    }
    setRecvState(LT_RECV_ST_ACK);//不足一个ack包，等待下次继续处理
    return readLen;
}

//返回已处理长度
int BtMsghandler::readRcvPkg(const unsigned char *data, int dataLen)
{
    if (NULL == m_pRecvPkg) {
        LOG(INFO)<<"readRcvPkg, create new rcvPkg object";
        createNewRcvPkg(NULL, 0);
    }else{
        LOG(INFO)<<"readRcvPkg， dataLen="<<dataLen;
    }
    setRecvState(LT_RECV_ST_RCV);
    int addLen = m_pRecvPkg->addData(data, dataLen);
    if (m_pRecvPkg->m_isPkgOk) {
        addToRecvList(m_pRecvPkg);
        m_pRecvPkg = NULL;
    }
    while(NULL!=m_pRecvPkg && m_pRecvPkg->m_dataLen>0
        && (m_pRecvPkg->m_bSkipToAck || m_pRecvPkg->m_bSkipToGoodRcv))
    {
        if (m_pRecvPkg->m_bSkipToAck) {
            LOG(INFO)<<"readRcvPkg, m_bSkipToAck";
            int lastLen =
                    m_pRecvPkg->m_dataLen > LT_ACK_PKG_LEN ? m_pRecvPkg->m_dataLen - LT_ACK_PKG_LEN
                                                           : 0;//跳转到ack包处理，可能超出12，剩余部分仍旧按rcv包处理
            int acktmpLen = lastLen == 0 ? m_pRecvPkg->m_dataLen
                                         : LT_ACK_PKG_LEN;//ack数据长度：如果剩余长度为0说明全部都是ack数据，否则是12
            setRecvState(LT_RECV_ST_NONE);
            readAckPkg(m_pRecvPkg->m_pData, acktmpLen);
            if(lastLen>0){
                //继续处理rcv剩余数据skip,跳过ack包的部分
                LOG(INFO)<<"readRcvPkg, next skip";
                m_pRecvPkg->skip();
                setRecvState(LT_RECV_ST_RCV);
            }else{
                delete m_pRecvPkg; m_pRecvPkg=NULL;//rcv数据处理完，直接删掉。
                LOG(INFO)<<"readRcvPkg, delete m_pRecvPkg";
            }
        }else{//  m_pRecvPkg->m_bSkipToGoodRcv
            LOG(INFO)<<"readRcvPkg, m_bSkipToGoodRcv";
            addToRecvList(m_pRecvPkg);
            m_pRecvPkg = NULL;
        }
    }
    if (NULL==m_pRecvPkg || m_pRecvPkg->m_dataLen == 0) {
        setRecvState(LT_RECV_ST_NONE);
    }
    return addLen;
}
void BtMsghandler::createNewRcvPkg(const unsigned char* data, int  dataLen)
{
    if(NULL!=m_pRecvPkg){
        delete m_pRecvPkg;
        m_pRecvPkg=NULL;
    }
    m_pRecvPkg=new CLtRecvPackage(data, dataLen);
    if(NULL==m_pRecvPkg){
        LOG(ERROR)<<"createNewRcvPkg failed!";
    }
}
int BtMsghandler::getPkgDelay()
{
    return m_pkgDelayMs;
}
void BtMsghandler::handleFirstPackage(const unsigned char **ppData, int* len){
    LOG(INFO) << "start handleFirstPackage, len="<<*len<<",m_posRecvPacket="<<m_posRecvPacket;
    while(*len) {
        switch (m_posRecvPacket) {
            case 0:
                if (*ppData[0] == 187) {//0xBB
                    m_bRespondPacket = true;
                    m_bErrReport = false;
                    LOG(INFO) << " recv firstPkg: BB";
                } else if (*ppData[0] == 170) {//0xAA
                    if(isSending()){
                        LOG(INFO) << "in sending mode(app->bleDev), ignore bleDev->app package";
                        m_posRecvPacket=0;
                        *len=0;
                        recv_sta=S0_Recv;
                        return;
                    }
                    LOG(INFO) << " recv firstPkg: AA";
                    m_sumRecvPacket=0;
                    m_bRespondPacket = false;
                    m_bErrReport = false;
                    m_DataPos = m_DataLastPos;
                    LOG(INFO) << "ble->app package begin byte byte0 \r\n";
                } else {                            // 缓存区中有残存数据，抛弃掉
                    LOG(INFO) << " recv firstPkg: otherByte";
                    (*len)--;
                    (*ppData)++;
                    LOG(INFO) << "another byte";
                    continue;
                }
                break;
            case 1:
                if (m_bRespondPacket) {
                    if (*ppData[0] != 0) {
                        m_bErrReport = true;
                        LOG(INFO) << "ble repsond package byte1 error";
                    }
                } else {
                    m_lenRecvPacket = *ppData[0];
                }
                break;
            case 2:
                if (m_bRespondPacket) {
                    if (*ppData[0] != 12) {
                        m_bErrReport = true;
                        LOG(INFO) << "ble repsond package byte2 length error";
                    } else {
                        m_lenRecvPacket = 12;
                    }
                    m_checkRecvPacket = (0xBB + (*ppData[0]));
                } else {
                    m_lenRecvPacket = (m_lenRecvPacket << 8) + (*ppData[0]);
                }
                break;
            case 3:
                if (m_bRespondPacket) {
                    if(!m_pSendData){             // 这种情况是不会出现的，只有在没有发送数据就接到应答包才发生
                        LOG(INFO) << "no sending to ble , ble repsond 3";
                        break;
                    }
                    if (((DataInfo*)m_pSendData)->taskId != *ppData[0]) {
                        LOG(INFO) << "ble respond taskId error";
                        m_bErrReport = true;
                    }
                    m_checkRecvPacket += (*ppData[0]);
                } else {
                    if (m_noRecvPacket) {
                        if (m_idRecvTask != *ppData[0]) {
                            m_bErrReport = true;
                        }
                    } else {
                        m_idRecvTask = *ppData[0];
                    }
                }
                break;
            case 4:
                if (m_bRespondPacket) {
                    if(!m_pSendData){             // 这种情况是不会出现的，只有在没有发送数据就接到应答包才发生
                        LOG(INFO) << "no sending to ble , ble repsond 4";
                        break;
                    }
                    if (((DataInfo*)m_pSendData)->storeId != *ppData[0]) {
                        LOG(INFO) << "ble respond storeId error";
                        m_bErrReport = true;
                    }
                    m_checkRecvPacket += (*ppData[0]);
                } else {
                    if (m_noRecvPacket) {
                        if (m_idRecvStore != *ppData[0]) {
                            m_bErrReport = true;
                        }
                    } else {
                        m_idRecvStore = *ppData[0];
                    }
                }
                break;
            case 5:
                if (m_bRespondPacket) {
                    if(!m_pSendData){             // 这种情况是不会出现的，只有在没有发送数据就接到应答包才发生
                        LOG(INFO) << "no sending to ble , ble repsond 5";
                        break;
                    }
                    if (*ppData[0] != m_pSendData[sizeof(DataInfo) + 5] ) {
                        LOG(INFO) << "ble repsond sum package byte5 error";
                        m_bErrReport = true;
                    }
                    m_checkRecvPacket += (*ppData[0]);
                } else {
                    if (m_noRecvPacket) {
                        if (((m_sumRecvPacket >> 8) & 0xff) != (*ppData[0])) {
                            m_bErrReport = true;
                            LOG(INFO) << " recv firstPkg: 5 err1";
                        }else{
                            LOG(INFO) << " recv firstPkg: 5 recv,m_noRecvPacket="<<m_noRecvPacket<<",m_sumRecvPacket="<<m_sumRecvPacket;
                        }
                    } else {
                        m_sumRecvPacket = *ppData[0];
                        LOG(INFO) << " recv firstPkg: 5 recv,2 m_noRecvPacket="<<m_noRecvPacket<<",m_sumRecvPacket="<<m_sumRecvPacket;
                    }
                }
                break;
            case 6:
                if (m_bRespondPacket) {
                    if(!m_pSendData){             // 这种情况是不会出现的，只有在没有发送数据就接到应答包才发生
                        LOG(INFO) << "no sending to ble , ble repsond 6";
                        break;
                    }
                    if (*ppData[0] != m_pSendData[sizeof(DataInfo) + 6]){
                        LOG(INFO) << "ble repsond sum package byte6 error";
                        m_bErrReport = true;
                    }
                    m_checkRecvPacket += (*ppData[0]);
                } else {
                    if (m_noRecvPacket) {
                        if ((m_sumRecvPacket & 0xff) != (*ppData[0])) {
                            m_bErrReport = true;
                            LOG(INFO) << " recv firstPkg: 6 err1,m_noRecvPacket="<<m_noRecvPacket<<",m_sumRecvPacket="<<m_sumRecvPacket;
                        }
                    } else {
                        m_sumRecvPacket = (m_sumRecvPacket << 8) + *ppData[0];
                        LOG(INFO) << " recv firstPkg: 6,m_noRecvPacket="<<m_noRecvPacket<<",m_sumRecvPacket="<<m_sumRecvPacket;
                    }
                }
                break;
            case 7:
                if (m_bRespondPacket) {
                    if(!m_pSendData){             // 这种情况是不会出现的，只有在没有发送数据就接到应答包才发生
                        LOG(INFO) << "no sending to ble , ble repsond 7";
                        break;
                    }
                    if (*ppData[0] != m_pSendData[sizeof(DataInfo) + 7]) {
                        LOG(INFO) << " recv firstPkg: 7 err1";
                        m_bErrReport = true;
                    }
                    m_checkRecvPacket += (*ppData[0]);
                } else {
                    m_seqRecvPacket = *ppData[0];
                }
                LOG(INFO) << " recv firstPkg: 7,m_seqRecvPacket="<<m_seqRecvPacket;
                break;
            case 8:
                if (m_bRespondPacket) {
                    if(!m_pSendData){             // 这种情况是不会出现的，只有在没有发送数据就接到应答包才发生
                        LOG(INFO) << "no sending to ble , ble repsond 8";
                        break;
                    }
                    if (*ppData[0] != m_pSendData[sizeof(DataInfo) + 8]) {
                        LOG(INFO) << "ble repsond package number byte8 error";
                        m_bErrReport = true;
                    }
                    m_checkRecvPacket += (*ppData[0]);
                } else {
                    m_seqRecvPacket = (m_seqRecvPacket << 8) + *ppData[0];
                    if (m_seqRecvPacket != m_noRecvPacket) {
                        LOG(INFO) << "sending to ble, seq error";
                        m_bErrReport = true;
                    }
                    // 计算整个任务需要的申请总字节数，按每包最大489算。
                    if(m_seqRecvPacket == 0){
                        if(m_pRecvData != NULL){
                            delete[] m_pRecvData;
                        }
                        int totalBytes = m_sumRecvPacket * (PACKAGE_SIZE - 11);
                        m_pRecvData = new unsigned char[totalBytes];
                        memset(m_pRecvData, 0, totalBytes);
                        LOG(INFO) << "creating package for sending 500bytes package";
                    }
                    m_checkRecvPacket = (0xAA +
                                         ((m_lenRecvPacket >> 8) & 0xff) +
                                         (m_lenRecvPacket & 0xff)
                                         + m_idRecvTask + m_idRecvStore
                                         + ((m_sumRecvPacket >> 8) & 0xff) +
                                         (m_sumRecvPacket & 0xff)
                                         + ((m_seqRecvPacket >> 8) & 0xff) +
                                         (m_seqRecvPacket & 0xff)
                    );
                    (*len)--;
                    (*ppData)++;
                    m_posRecvPacket++;
                    recv_sta = S_RecvNnPacket;
                    return;
                }
                break;
            case 9:
                if (m_bRespondPacket) {
                    if(!m_pSendData){             // 这种情况是不会出现的，只有在没有发送数据就接到应答包才发生
                        LOG(INFO) << "no sending to ble , ble repsond 9";
                        break;
                    }
                    m_RespondOK = *ppData[0];
                    m_checkRecvPacket += (*ppData[0]);
                }
                break;
            case 10:
                if (m_bRespondPacket) {
                    if (m_checkRecvPacket != *ppData[0]) {
						LOG(INFO) << "ble respond check error \r\n";
                        m_bErrReport = true;
                    }
                }
                break;
            case 11:
                if (m_bRespondPacket) {
                    LOG(INFO) << "ble respond endbyte 0x55 (ack)\r\n";
                    m_posRecvPacket = 0;
                    if (*ppData[0] != 0x55) {
                        LOG(INFO) << "ble respond endbyte error \r\n";
                        m_bErrReport = true;
                    } /*else{
                        m_bErrReport = false;
                    }*/
                    (*len)--;

                    if ( !m_bErrReport) {
                        if(!m_pSendData){             // 这种情况是不会出现的，只有在没有发送数据就接到应答包才发生
                            LOG(INFO) << "no sending to ble , ble repsond 8 \r\n";
                            return;
                        }
                        int dtDataLen=m_pSendData?((DataInfo *) m_pSendData)->dataLen:0;
                        char dtTaskId=m_pSendData?((DataInfo *) m_pSendData)->taskId:(char)0;
                        char dtStoreId=m_pSendData?((DataInfo *) m_pSendData)->storeId:(char)0;
                        short thisBodySize = (m_pSendData[sizeof(DataInfo) + 1] << 8) + m_pSendData[sizeof(DataInfo) + 2];
                        char endChar = m_pSendData[sizeof(DataInfo) + thisBodySize - 1];
                        if (m_RespondOK == 1) {
                            if(endChar == 0x55) {
                                LOG(INFO) << "ble respond indicating that sending to ble success (ack)";
                                //m_pListener->onSendDataResult(0, (DataInfo *) m_pSendData);
                                //doStopSend(SENDRLT_SUCC, dtDataLen, dtTaskId, dtStoreId);
                            }
                            Respond_handle(true);
                        } else {
                            if(endChar == 0x55) {
                                LOG(INFO) << "ble respond indicating that sending to ble error (ack), need reSend";
                                //m_pListener->onSendDataResult(1, (DataInfo *) m_pSendData);
                                //doStopSend(SENDRLT_SRVFAIL, dtDataLen, dtTaskId, dtStoreId);
                            }
                            Respond_handle(false);
                        }
                        return;
                    }
                }
                return;
            default:
                break;
        }
        (*len)--;
        (*ppData)++;
        m_posRecvPacket++;
    }
}
void BtMsghandler::handleSubPackage(const unsigned char **ppData, int *len){
    const unsigned char *pData = *ppData;
    LOG(INFO) << "handleSubPackage,begin,len="<<*len<<",recv_sta="<<recv_sta;
    while (1){
        switch (recv_sta){
            case S0_Recv:{
				LOG(INFO) << "handleSubPackage,S0_Recv: start sending or recving cycle";
                m_noRecvPacket = 0;
                m_checkRecvPacket = 0;
                m_posRecvPacket = 0;
                m_pRecvData = NULL;
                recv_sta = S_RecvN0Packet;
                m_bErrReport = false;
            }
                break;
            case S_RecvN0Packet:{
                LOG(INFO) << "handleSubPackage,S_RecvN0Packet: call handleFirstPackage";
                handleFirstPackage(ppData, len);
                return;
            }
            case S_RecvNnPacket: {
                LOG(INFO) << "handleSubPackage,S_RecvNnPacket: recving body from ble,m_lenRecvPacket="<<m_lenRecvPacket;
                short thisBodySize;
                if((m_lenRecvPacket - 11 - m_DataPos) > (*len)) {
                    thisBodySize = *len;
                } else{
                    thisBodySize = m_lenRecvPacket - m_DataPos - 11;
                }

                LOG(INFO) << "handleSubPackage,S_RecvNnPacket: thisBodySize="<<thisBodySize<<",m_DataPos="<<m_DataPos;
                for (int i = 0; i < thisBodySize; i++) {
                    m_checkRecvPacket += pData[i];
                }
                memcpy(&m_pRecvData[m_DataPos], pData, thisBodySize);
                m_DataPos += thisBodySize;
                m_posRecvPacket += thisBodySize;
                (*ppData) += thisBodySize;
                (*len) -= thisBodySize;

                // check
                if(m_posRecvPacket == (m_lenRecvPacket-2)) {
                    if((*len) > 0) {
                        if((const unsigned char)*ppData[0] != m_checkRecvPacket){
							LOG(INFO) << "recv data check error \r\n";
                            m_bErrReport = true;
                        }
                        (*ppData)++;
                        (*len)--;
                        m_posRecvPacket++;
                    }
                }

                // end
                if(m_posRecvPacket == (m_lenRecvPacket-1)) {
                    if (*len > 0) {
                        if(checkEnd(*ppData[0])){
							LOG(INFO) << "recv data end error \r\n";
                            m_bErrReport = true;
                        }
                        m_Endbyte = *ppData[0];
                        (*ppData)++;
                        (*len)--;
                        m_posRecvPacket++;
                    }
                }
            }
            if(m_posRecvPacket == m_lenRecvPacket){
                    if(m_bErrReport == true){
                        recv_sta = S_RecvErr;
                    } else{
                        recv_sta = S_RecvFinish;
                    }
                    break;
                } else {
                return;
            }
            case S_RecvFinish:
            {
                LOG(INFO) << "handleSubPackage,S_RecvFinish: recv last pkg";
                m_noRecvPacket++;
                if( (m_sumRecvPacket-1) == m_seqRecvPacket)   // 一级包齐备
                {
                    if(m_Endbyte != 0x55){
                        LOG(INFO) << "Recv package error";
                    }
                    if(m_bRespondPacket){
                        LOG(INFO) << "recv ack package";
                    }

                    DataInfo dataInfo(m_DataPos, m_idRecvTask, m_idRecvStore);
                    m_pListener->onRecvBleData(m_pRecvData, &dataInfo);
                    m_bRespondPacket=true;
                    delete[] m_pRecvData;
                    m_pRecvData = NULL;
                    recv_sta = S0_Recv;
                    m_DataLastPos = 0;
                }
                else {
                    m_DataLastPos = m_DataPos;
                }
                unsigned char SuccessRepond[12];
                makeReponseCode(SuccessRepond, 1);    // isOK == 1 表示接收成功
                m_pListener->sendToBaseBle(SuccessRepond, 12);
                LOG(INFO) << "Recv Success a package";
            }
                return;
            case S_RecvErr: {
                LOG(INFO) << "handleSubPackage,S_RecvErr";
                m_bErrReport = false;
                recv_sta = S_RecvN0Packet;
                unsigned char FailRepond[12];
                makeReponseCode(FailRepond, 0);
                m_pListener->sendToBaseBle(FailRepond, 12);
            }
                return;
            default:
                break;
        }
    }
}

// 向DEV层发送
int BtMsghandler::sendData(const unsigned char* businessDataExt, const DataInfo *dataInfoExt)
{
    short tempSeq = 0;
    const DataInfo* dataInfo=dataInfoExt;
    const unsigned char* businessData=businessDataExt;
    char* hzData=NULL;
    DataInfo tmpDataInfo(0,0,0);

    unsigned char *pPacket;

    if(isSending()){
        LOG(INFO) << "发送中，稍后再试";
        return 1;
    }

    setSending(true);
    resetReSendCnt();
    if(dataInfoExt->taskId==TASK_PIXELS) {
        //文字转点阵,使用转换后的data及长度
        int hzCnt = dataInfoExt->dataLen, bufferSize = 0;
        hzData = getGbkHzPixelsByVector((const char *) businessDataExt, hzCnt, bufferSize);
        if (NULL == hzData) {
            LOG(INFO) << "ERROR: sendData(TASK_PIXELS) getGbkHzPixelsByVector,NULL==hzData";
        }
        businessData = (const unsigned char *) hzData;
        tmpDataInfo.dataLen = bufferSize;
        tmpDataInfo.taskId = dataInfoExt->taskId;
        tmpDataInfo.storeId = dataInfoExt->storeId;
        dataInfo = &tmpDataInfo;
    }
    int  businessDataLen = dataInfo->dataLen;
    short SumPacket = (businessDataLen + 488) / 489;
    LOG(INFO)<<SW_VER_STR << "begin sending data to ble, SumPacket="<<SumPacket;

    do
    {
        pPacket = new unsigned char[((businessDataLen + 11) > 500 ? 500 : (businessDataLen + 11))+sizeof(DataInfo)];
        memcpy(pPacket, dataInfo, sizeof(DataInfo));
        pPacket[0 + sizeof(DataInfo)] = 0xAA;
        short tempLen;
        tempLen = businessDataLen > 489 ? 489 : businessDataLen;
        pPacket[1 + sizeof(DataInfo)] = ((11 + tempLen) >> 8) & 0xff;
        pPacket[2  + sizeof(DataInfo)] = (11 + tempLen) & 0xff;
        pPacket[3  + sizeof(DataInfo)] = dataInfo->taskId;
        pPacket[4 + sizeof(DataInfo)] = dataInfo->storeId;
        pPacket[5 + sizeof(DataInfo)] = (SumPacket >> 8) & 0xff;
        pPacket[6 + sizeof(DataInfo)] = SumPacket & 0xff;
        pPacket[7 + sizeof(DataInfo)] = (tempSeq >> 8) & 0xff;
        pPacket[8 + sizeof(DataInfo)] =  tempSeq & 0xff;
        memcpy(&pPacket[9 + sizeof(DataInfo)], businessData, tempLen);

        // 计算校验
        unsigned char check = 0;
        for (int i = 0; i < (tempLen + 9); ++i) {
            check += pPacket[i + sizeof(DataInfo)];
        }
        pPacket[9 + sizeof(DataInfo) + tempLen] = check;
        if((businessDataLen - tempLen) >  0)
        {
            pPacket[10 + sizeof(DataInfo) + tempLen] =  0x66;
        }
        else
        {
            pPacket[10 + sizeof(DataInfo) + tempLen] =  0x55;
        }
        m_sendList.push_back(pPacket);
        businessDataLen -= 489;
        tempSeq++;
    }while(businessDataLen > 0);
    if(!m_pSendData)
    {
        m_cv.notify_one();
    }
    if(NULL!=hzData) {
        delete[] hzData;
    }
	LOG(INFO)<<SW_VER_STR << "end sending data to ble";
    return 0;
}
int BtMsghandler::getMTU()
{
    return LT_BLE_SIZE;
}
int BtMsghandler::getNewMTU()
{
    return m_mtu;
}
int BtMsghandler::getNewMTUAct()
{
    return m_mtu-3;
}
void BtMsghandler::setNewMTU(int newMTU)
{
    m_mtu=newMTU;
    LOG(INFO)<<SW_VER_STR << "setNewMTU() " << m_mtu;
}
void BtMsghandler::setPkgDelay(int delayMs)
{
    m_pkgDelayMs=delayMs;
    LOG(INFO)<<SW_VER_STR << "setPkgDelay() delayMs="<<delayMs;
}
void BtMsghandler::onNotifySendToBaseBleResult(int result)
{
    LOG(INFO)<<SW_VER_STR << "onNotifySendToBaseBleResult() result="<<result;
    m_sndBleRlt=result;
    setSndBleRltGot(true);
}
bool BtMsghandler::isSending()
{
    std::lock_guard<std::mutex> lck(m_mutexSending);
    return m_bSending;
}
void BtMsghandler::setSending(bool b)
{
    std::lock_guard<std::mutex> lck(m_mutexSending);
    m_bSending=b;
}
// 通过APP层向蓝牙设备发送
#ifdef LT_BLE_ANDROID
extern void callJavaFuncSendToBaseBle(const unsigned char* data, const int dataLen);
void onPrintLogToJavaImp(const char* logmsg);
#endif
void BtSdkListener::sendToBaseBle(const unsigned char *basePkg, int pkgLen)
{
#ifdef LT_BLE_ANDROID
    callJavaFuncSendToBaseBle(basePkg, pkgLen);
#else
    if(pkgLen > 0) {
        NSData *data = [NSData dataWithBytes: basePkg length: pkgLen];
        dispatch_async(dispatch_get_main_queue(), ^{
            [[NSNotificationCenter defaultCenter] postNotificationName: SEND_TO_BASE_BLE object: data];
        });
    }
#endif
}
extern void callJavaFuncOnSendDataResult(int retCode, int dataLen, char taskId, char storeId);
void BtSdkListener::onSendDataResult(int retCode, int dataLen, char taskId, char storeId)
{
#ifdef LT_BLE_ANDROID
    callJavaFuncOnSendDataResult(retCode, dataLen, taskId, storeId);
#else
    NSMutableDictionary *recv = [[NSMutableDictionary alloc] init];
    [recv setObject: [NSNumber numberWithInt: retCode]  forKey: @"retCode"];
    [recv setObject: [NSNumber numberWithInt: dataLen] forKey: @"dataLen"];
    [recv setObject: [NSNumber numberWithChar: taskId] forKey: @"taskId"];
    [recv setObject: [NSNumber numberWithChar: storeId] forKey: @"storeId"];
    
    dispatch_async(dispatch_get_main_queue(), ^{
        [[NSNotificationCenter defaultCenter] postNotificationName: ON_SEND_DATA_RESULT object: recv];
    });
#endif
}
#ifdef LT_BLE_ANDROID
extern void callJavaFuncOnRecvBleData(const unsigned char *businessData, const DataInfo* dataInfo);
#endif
void BtSdkListener::onRecvBleData(const unsigned char *businessData, const DataInfo *dataInfo)
{
#ifdef LT_BLE_ANDROID
    callJavaFuncOnRecvBleData(businessData, dataInfo);
#else
    if(NULL != dataInfo && NULL != businessData) {
        NSMutableDictionary *recv = [[NSMutableDictionary alloc] init];
        NSData *data = [NSData dataWithBytes: businessData length: dataInfo->dataLen];
        [recv setObject: data forKey: @"businessData"];
        [recv setObject: [NSNumber numberWithInt: dataInfo->dataLen] forKey: @"dataLen"];
        [recv setObject: [NSNumber numberWithChar: dataInfo->taskId] forKey: @"taskId"];
        [recv setObject: [NSNumber numberWithChar: dataInfo->storeId] forKey: @"storeId"];
        
        dispatch_async(dispatch_get_main_queue(), ^{
            [[NSNotificationCenter defaultCenter] postNotificationName: ON_RECV_BEL_DATA object: recv];
        });
    }
#endif
}

bool BtMsghandler::checkEnd(const unsigned char data)
{
    bool bEndErr = true;
    if(m_seqRecvPacket == (m_sumRecvPacket-1))
    {
        if(data == 0x55){
            bEndErr = false;
        }
    } else {
        if(data == 0x66){
            bEndErr = false;
        }
    }
    return bEndErr;
}

void BtMsghandler::makeReponseCode(unsigned char *pReponseCode, char isOK)
{
    pReponseCode[0] = 0xBB;
    pReponseCode[1] = 0;
    pReponseCode[2] = 12;
    pReponseCode[3] = m_idRecvTask;
    pReponseCode[4] = m_idRecvStore;
    pReponseCode[5] = (m_sumRecvPacket >> 8) & 0xff;
    pReponseCode[6] = m_sumRecvPacket & 0xff;
    pReponseCode[7] = (m_seqRecvPacket >> 8) & 0xff;
    pReponseCode[8] = m_seqRecvPacket & 0xff;
    pReponseCode[9] = isOK;
    pReponseCode[10] = 0;
    for(int i = 0; i < 10; i++) {
        pReponseCode[10] += pReponseCode[i];
    }
    pReponseCode[11] = 0x55;
}
//发送处理线程
void BtMsghandler::makesubPacketandSendTask()
{
    std::list<unsigned char *>::iterator it ;
    int coutTimeout = 0;
    const unsigned char *pData;
    while(1){
        if(!m_pSendData) {
			LOG(INFO)<<SW_VER_STR << "sendThread wait for condition";
            m_cv.wait(*m_lck);
			LOG(INFO)<<SW_VER_STR << "sendThread gain condition";
            if(m_exitSendThread){
				LOG(INFO)<<SW_VER_STR << "sendThread exit";
                doStopSend(SENDRLT_THEXIT, 0, 0, 0);
                return;
            }
            if (m_sendList.size() == 0){
                doStopSend(SENDRLT_END, 0, 0, 0);
                continue;
            }
            setSending(true);
            it = m_sendList.begin();
            pData = *it;
            m_sendList.pop_front();
        } else{
#ifdef DIRECT_TRANS_BLE
            if(false){
#else
            LOG(INFO)<<SW_VER_STR<<"begin wait ACK from device...";
            //if(m_cv.wait_for(*m_lck, std::chrono::milliseconds(TO_TRESMITT_RECVRESPOND)) == std::cv_status::timeout){   // 超时
            if(waitForBleDevAck()==1){ // 超时
#endif
                int dtDataLen=m_pSendData?((DataInfo *) m_pSendData)->dataLen:0;
                char dtTaskId=m_pSendData?((DataInfo *) m_pSendData)->taskId:(char)0;
                char dtStoreId=m_pSendData?((DataInfo *) m_pSendData)->storeId:(char)0;
				LOG(INFO)<<SW_VER_STR << "sendThread timeout";
                coutTimeout++;
                pData = m_pSendData;
                if(m_exitSendThread){
                    doStopSend(SENDRLT_THEXIT, dtDataLen, dtTaskId, dtStoreId);
                    return;
                }
                if(coutTimeout > 3) {
                    coutTimeout = 0;
                    doStopSend(SENDRLT_TMOUT, dtDataLen, dtTaskId, dtStoreId);
					LOG(INFO)<<SW_VER_STR << "sendThread timeout and report";
                    //m_pListener->onSendDataResult(2, (DataInfo*)m_pSendData);
                    clrSendList();
                    continue;
                }
            } else{                        // 得到应答
                int dtDataLen=m_pSendData?((DataInfo *) m_pSendData)->dataLen:0;
                char dtTaskId=m_pSendData?((DataInfo *) m_pSendData)->taskId:(char)0;
                char dtStoreId=m_pSendData?((DataInfo *) m_pSendData)->storeId:(char)0;
                coutTimeout = 0;
#ifdef DIRECT_TRANS_BLE
                if(true){
                    LOG(INFO)<<SW_VER_STR << "DIRECT_TRANS_BLE mode";
#else
				if(m_bIndict_OK) {         // 传输过程正确
#endif
                    delete[] m_pSendData;
                    m_pSendData = NULL;
                    if (m_exitSendThread) {
						LOG(INFO)<<SW_VER_STR << "sendThread exit";
                        doStopSend(SENDRLT_THEXIT, dtDataLen, dtTaskId, dtStoreId);
                        return;
                    }
                    if (m_sendList.size() == 0) {
                        LOG(INFO)<<SW_VER_STR << "send end (already notify)";
                        //doStopSend(SENDRLT_END, dtDataLen, dtTaskId, dtStoreId);
                        doStopSend(SENDRLT_SUCC, dtDataLen, dtTaskId, dtStoreId);
                        continue;
                    }
					LOG(INFO)<<SW_VER_STR << "sendThread: get next piece from list";
                    it = m_sendList.begin();
                    pData = *it;
                    m_sendList.pop_front();
                } else {                  // 传输过程有问题，重传
                    if (canReSend(true)) {
                        LOG(INFO) << SW_VER_STR << "sendThread resend";
                        pData = m_pSendData;
                    }else{
                        doStopSend(SENDRLT_SRVFAIL, dtDataLen, dtTaskId, dtStoreId);
				    }
                    if(m_exitSendThread){
                        LOG(INFO)<<SW_VER_STR << "exit thread";
                        doStopSend(SENDRLT_THEXIT, dtDataLen, dtTaskId, dtStoreId);
                        return;
                    }
                }
            }
        }

        m_pSendData = pData;
        const unsigned char *pData_ = &pData[sizeof(DataInfo)];
        short len = (pData_[1] << 8) + pData_[2];
        short len_ = len;
        short pos = 0;
        short lenSubPacket;
        int reTryCnt=0;
        const int MAX_RETRY_CNT=5;
        int remainListSize=m_sendList.size();
        do {
            lenSubPacket = len > getNewMTUAct() ? getNewMTUAct() : len;
            LOG(INFO)<<SW_VER_STR << "sendThread a subpackage, lenSubPacket="<<lenSubPacket
                <<", CurPkgRemainLen="<<len<<",remainPkgCnt="<<remainListSize;
            m_pListener->sendToBaseBle(&pData_[pos], lenSubPacket);
            
            //std::chrono::milliseconds dura(getPkgDelay());
            //std::this_thread::sleep_for(dura);
            int result=waitForSendBaseBleResult();
            if(0==result){
                reTryCnt=0;
                len -= lenSubPacket;
                pos += lenSubPacket;
            }else if(++reTryCnt>MAX_RETRY_CNT){
                //retry max cnt
                LOG(INFO)<<SW_VER_STR << "send failed,"; // need exit,and callback
            }
        } while (len > 0);

        LOG(INFO)<<SW_VER_STR << "Send a package";
    }
}
//加入
void BtMsghandler::addToRecvList(CLtRecvPackage* pPkg)
{
    std::list<CLtRecvPackage*>::iterator it;
    if(NULL==pPkg || !pPkg->m_isPkgOk){
        LOG(INFO)<<"addToRecvList() NULL==pPkg || !pPkg->m_isPkgOk";
        return;
    }
    unsigned char taskId=pPkg->m_header.taskId;
    unsigned char storeId=pPkg->m_header.storeId;
    unsigned short pkgSum=pPkg->m_header.pkgSum;
    unsigned short pkgSeq=pPkg->m_header.pkgSeq;
    {
        std::lock_guard<std::mutex> lck(m_mutexRecvList);
//遍历1：校验数据包都合法（相同数据类型）
        int cnt=0;
        for (it = m_recvPkgList.begin(); it != m_recvPkgList.end(); )
        {
            bool isBadPkg=false;
            CLtRecvPackage* pTmpPkg=(*it);
            if(pTmpPkg->m_header.taskId==taskId && pTmpPkg->m_header.storeId==storeId && pTmpPkg->m_header.pkgSum==pkgSum){
                if(pTmpPkg->m_header.pkgSeq==pkgSeq){
                    isBadPkg=true;
                }
            }else{
                isBadPkg=true;
            }
            if(isBadPkg){
                it=m_recvPkgList.erase(it);
                delete pTmpPkg;
                --m_recvPkgListCount;
            }else{
                ++it;
            }
        }
        m_recvPkgList.push_back(pPkg);
        ++m_recvPkgListCount;
    }
    LOG(INFO)<<"addToRecvList() taskId="<<taskId<<",storeId="<<storeId<<",pkgSum="<<pkgSum
            <<",pkgSeq="<<pkgSeq<<",m_recvPkgListCount="<<m_recvPkgListCount;
    m_cvRecvList.notify_one();//通知线程2处理list
}
//返回最后一个pkg，及list中pkg总数pkgCnt
CLtRecvPackage* BtMsghandler::getLastRecvPkg(int & pkgCnt)
{
    std::lock_guard<std::mutex> lck(m_mutexRecvList);
    if(m_recvPkgList.empty()){
        return NULL;
    }
    CLtRecvPackage* pRecvPkg=m_recvPkgList.back();
    pkgCnt=m_recvPkgListCount;
    return pRecvPkg;
}

//发送处理线程
void BtMsghandler::threadRecvBle()
{
    CLtRecvPackage* pRecvPkg=NULL;
    std::list<CLtRecvPackage*>::iterator it;
    unsigned short pkgSum=0;
    unsigned short curPkgSeq=0;
    unsigned char * pAllData=NULL;
    unsigned char * pTmp=NULL;
    int totalLen=0;
    int pkgCnt=0;
    while(1){
        if(m_exitSendThread){
            LOG(INFO)<<SW_VER_STR << "threadRecvBle() exit";
            return;
        }
        m_cvRecvList.wait_for(*m_lckRecvList, std::chrono::milliseconds(5000));//最多等5s
        pRecvPkg=getLastRecvPkg(pkgCnt);
        if(NULL==pRecvPkg || pkgCnt<pRecvPkg->m_header.pkgSum) {
            //m_cvRecvList.wait(*m_lckRecvList);
            continue;
        }

        if(m_exitSendThread){
            LOG(INFO)<<SW_VER_STR << "threadRecvBle() exit2";
            return;
        }
        LOG(INFO)<<SW_VER_STR<<"threadRecvBle() begin deal recvPkg...";
        pkgSum=pRecvPkg->m_header.pkgSum;
        curPkgSeq=pRecvPkg->m_header.pkgSeq;
        if(curPkgSeq+1==pkgSum){
            //一级包齐备
            totalLen = (pkgSum-1) * (LT_PKG_LEN - 11)+(pRecvPkg->m_header.pkgLen-11);
            if(totalLen<=0){
                continue;
            }
            pAllData = new unsigned char[totalLen];
            pTmp=pAllData;
        }else{
            continue;
        }
        LOG(INFO)<<"threadRecvBle() makeAllData: totalLen="<<totalLen<<",pkgSum="<<pkgSum;
        DataInfo dataInfo(totalLen, pRecvPkg->m_header.taskId, pRecvPkg->m_header.storeId);
        pRecvPkg=NULL;
        {
            std::lock_guard<std::mutex> lck(m_mutexRecvList);
            //遍历：拼接数据，同时删除pkg对象指针（及缓冲区）
            for (it = m_recvPkgList.begin(); it != m_recvPkgList.end(); ++it)
            {
                unsigned short curLen=(*it)->getBusinessDataLen();
                memcpy(pTmp, (*it)->getBusinessData(), curLen);
                LOG(INFO)<<"threadRecvBle() makeAllData: pkgSeq="<<(*it)->m_header.pkgSeq<<",curLen="<<curLen;
                pTmp=pTmp+curLen;
                delete (*it);
            }
            m_recvPkgList.clear();
            m_recvPkgListCount=0;
        }

        m_pListener->onRecvBleData(pAllData, &dataInfo);
        delete[] pAllData;
        pAllData = NULL;
    }
}

////retCode 0发送成功，1服务端回应发送失败，2发送超时，3本地发送失败  100退出线程
void BtMsghandler::doStopSend(int retCode, int dataLen, char taskId, char storeId)
{
    bool oldSendFlag=isSending();
    setSending(false);
    if(oldSendFlag){

    }
    this->recv_sta=S0_Recv;
    this->m_posRecvPacket=0;
    LOG(INFO)<<SW_VER_STR << "doStopSend,retCode="<<retCode;
    m_pListener->onSendDataResult(retCode, dataLen, taskId, storeId);

}
// 处理回应包
void BtMsghandler::Respond_handle(bool bOk)
{
    LOG(INFO)<<SW_VER_STR << "Recv Respond,ack="<<(bOk?"1":"0");
    m_bIndict_OK = bOk;
    //m_cv.notify_one();
    setBleDevAckGot(true);
}

// rtn 1 timeout, 0 success
int BtMsghandler::waitForBleDevAck()
{
    LOG(INFO)<<SW_VER_STR<<"waitForBleDevAck...";
    if(isBleDevAckGot()){
        LOG(INFO)<<SW_VER_STR<<"waitForBleDevAck, m_bIndict_OK="<<m_bIndict_OK<<",fast";
        setBleDevAckGot(false);
        return 0;
    }
    if(m_cv.wait_for(*m_lck, std::chrono::milliseconds(TO_TRESMITT_RECVRESPOND)) == std::cv_status::timeout){
        return 1;
    }

    LOG(INFO)<<SW_VER_STR<<"waitForBleDevAck, m_bIndict_OK="<<m_bIndict_OK;
    setBleDevAckGot(false);
    return 0;
}
int BtMsghandler::waitForSendBaseBleResult()
{
    LOG(INFO)<<SW_VER_STR<<"waitForSendBaseBleResult...";
    if(isSndBleRltGot()){
        LOG(INFO)<<SW_VER_STR<<"waitForSendBaseBleResult, m_sndBleRlt="<<m_sndBleRlt<<",fast";
        setSndBleRltGot(false);
        return m_sndBleRlt;
    }

    m_cvSndBleRlt.wait(*m_lckSndBleRlt);
    LOG(INFO)<<SW_VER_STR<<"waitForSendBaseBleResult, m_sndBleRlt="<<m_sndBleRlt;
    setSndBleRltGot(false);
    return m_sndBleRlt;
}
void BtMsghandler::setBleDevAckGot(bool b)
{
    std::lock_guard<std::mutex> lck(m_mutexBleDevAckGot);
    m_bBleDevAckGot=b;
    if(b){
        //delay，确保wait先执行
        std::chrono::microseconds dura(100);//微秒
        std::this_thread::sleep_for(dura);
        m_cv.notify_one();
    }

}
void BtMsghandler::setSndBleRltGot(bool b)
{
    std::lock_guard<std::mutex> lck(m_mutexBSndBleRltGot);
    m_bSndBleRltGot=b;
    if(b){
        //delay，确保wait先执行
        std::chrono::microseconds dura(100);//微秒
        std::this_thread::sleep_for(dura);
        m_cvSndBleRlt.notify_one();
    }

}
bool BtMsghandler::isBleDevAckGot()
{
    std::lock_guard<std::mutex> lck(m_mutexBleDevAckGot);
    return m_bBleDevAckGot;
}  
bool BtMsghandler::isSndBleRltGot()
{
    std::lock_guard<std::mutex> lck(m_mutexBSndBleRltGot);
    return m_bSndBleRltGot;
}

bool BtMsghandler::isRecvStateRcv()
{
    return LT_RECV_ST_RCV==m_recvState;
}
bool BtMsghandler::isRecvStateAck()
{
    return LT_RECV_ST_ACK==m_recvState;
}
bool BtMsghandler::isRecvStateNone()
{
    return LT_RECV_ST_NONE==m_recvState;
}
void BtMsghandler::setRecvState(int state)
{
    m_recvState=state;
}
void BtMsghandler::resetReSendCnt(){
    m_reSendCnt=0;
}
bool BtMsghandler::canReSend(bool useOneCnt) {
    if(useOneCnt)
        ++m_reSendCnt;
    return m_reSendCnt<RE_SEND_MAX_CNT;
}

 